#include <string>
#include <memory>
#include "epoll_conn.hpp"
#include "../common/protocol.hpp"
#include "../common/logmessage.hpp"

class Calculator
{
    Request _req;
    Response _rsp;
    std::shared_ptr<Link> _link_sptr;

public:
    Calculator(std::shared_ptr<Link> link_sptr)
        : _req({0, 0, 0}), _rsp({0, 0}), _link_sptr(link_sptr)
    {
    }

    // 负责计算，处理结构化数据
    void Calculate()
    {
        switch (_req._op)
        {
        case '+':
            _rsp._ret = _req._l + _req._r;
            break;
        case '-':

            _rsp._ret = _req._l - _req._r;
            break;
        case '*':
            _rsp._ret = _req._l * _req._r;
            break;
        case '/':
            if (_req._r == 0)
                _rsp._code = 1;
            else
                _rsp._ret = _req._l / _req._r;
            break;
        case '%':
            if (_req._r == 0)
                _rsp._code = 2;
            else
                _rsp._ret = _req._l % _req._r;
            break;
        default:
            _rsp._code = 3;
            break;
        }
    }

    // 将接收缓冲区中的数据进行分包和反序列化，生成结构化的请求数据
    void AnalyseReq()
    {
        string &inbuf = _link_sptr->GetInbuf();
        // 协议解析，得到一个完整的报文
        std::string package = Decode(inbuf);
        if (package.empty()) return;
        LogMessage(NORMAL, "%s", package.c_str());
        // 反序列化，字节流->结构化数据
        _req.Deserialize(package);

    }

    // 将结构化的响应数据进行序列化和封装，并推送到发送缓冲区中设置套接字写事件监听
    void PackageRsp()
    {
        // 序列化业务的处理结果
        std::string respstr = _rsp.Serialize();
        // std::cout << respstr << std::endl;
        // 添加长度信息，形成一个完成的报文
        respstr = Encode(respstr);
        string& outbuf = _link_sptr->GetOutbuf();
        outbuf += respstr;
        //要手动打开写事件的监听，并且写完就会自动关闭。
        _link_sptr->ModEvent(_link_sptr->_event | EPOLLOUT); // !!!
    }
};
